import styles from "./index.module.less";
import classnames from "classnames";
import { useState, useEffect, useRef } from "react";
import { Button, Input, Typography, Flex, Avatar, List, Modal } from "antd";
import { io } from "socket.io-client";
const { Title } = Typography;
const { confirm } = Modal;

let pc = null;

function SocketIndex() {
  const [socketObj, setSocket] = useState(null);
  const [loginValue, setLoginValue] = useState("xiaoyang");
  const [messageList, setMessageList] = useState([]);
  const [userList, setUserList] = useState([]); //用户列表
  const [isLogin, setLoginStatus] = useState(false);
  const [userInfo, setUserInfo] = useState(null); //当前我的信息
  const [receiveUser, setReceiveUser] = useState(null); //当前的说话人
  const [sendMessage, setMessage] = useState("");

  // const [RTCpc, setRTC] = useState(null);

  const localVideoRef = useRef(null);
  const remoteVideoRef = useRef(null); //远程的

  // useEffect(() => {
  //   const pc = new RTCPeerConnection(null);
  //   setRTC(pc);

  function createPeerConnection(callback) {
    pc = new RTCPeerConnection(null);
    // pc.onicecandidate = handleIceCandidate;
    // pc.ontrack = handleRemoteStreamAdd;
    callback(pc);
  }

  function onLogin() {
    const nowUsername = loginValue;
    if (!nowUsername) {
      console.warn("不可为空");
      return;
    }
    const thisUserInfo = {
      username: nowUsername,
      now: Date.now(),
      avatar: `https://api.dicebear.com/7.x/miniavs/svg?seed=${
        Math.floor(Math.random() * 10) + 1
      }`,
    };
    // 登录
    const socket = io("http://192.168.1.106:3000", {
      query: thisUserInfo,
    });

    socket.on("connect", () => {
      console.log("连接成功~~~", socket.id);
      setUserInfo({
        ...thisUserInfo,
        socketId: socket.id,
      });
      setLoginStatus(true);
      setSocket(socket);
    });

    socket.on("update-userlist", (userInfo) => {
      const { userlist } = userInfo;
      // console.log("update-userlist", userlist);
      setUserList((oldlist) => {
        return oldlist.concat(userlist);
      });
    });

    socket.on("user-logout", (userinfo) => {
      setUserList((oldlist) => {
        return oldlist.filter((item) => item.socketId != userinfo.socketId);
      });
    });

    // 单独给我的消息
    socket.on("user-chat-private", (res) => {
      console.log("user-chat", res);
      // const { message, userinfo, receiver } = res;

      setMessageList((oldlist) => {
        return oldlist.concat(res);
      });
    });

    handlerRTC(socket);

    socket.on("disconnect", () => {
      setLoginStatus(false);
      setUserList([]);
      setMessageList([]);
    });
  }

  function onLogout() {
    socketObj.disconnect();
    setLoginStatus(false);
  }

  // 连接用户
  function handleUserSay(item) {
    socketObj.emit(
      "get-messagelist",
      { id: socketObj.id, username: loginValue },
      (e) => {
        // console.log("获取消息列表", e);
      }
    );
    setReceiveUser({
      user: item,
    });

    // localStream.getTracks().forEach((track) => pc.addTrack(track, localStream)); //pc添加媒体流
  }

  // 发送消息
  function onSendMessage() {
    // 我和别人说话
    socketObj.emit("user-say", {
      receiver: receiveUser.user,
      message: sendMessage,
    });
  }

  function handlerRTC(socket) {
    //B端接收 offer
    socket.on("peer-offer", async (res) => {
      console.log("B端peer-offer", res);
      // 这里现在是B端接收到的 offer
      const { offer, user } = res;
      setReceiveUser({ user });
      confirm({
        title: "接听电话˝",
        content: "接听",
        onOk: async () => {
          createPeerConnection(() => {
            pc.onicecandidate = (e) => {
              if (e.candidate) {
                const candidate = {
                  candidateJson: {
                    label: e.candidate.sdpMLineIndex,
                    id: e.candidate.sdpMid,
                    candidate: e.candidate.candidate,
                  },
                  user,
                };
                console.log("BB发送ice");
                socket.emit("candidate", candidate);
              }
            };
            //获取远端媒体流处理
            // handleRemoteStreamAdd
            pc.ontrack = (e) => {
              const remoteStream = e.streams[0];
              console.log("远端媒体流", e.streams);
              remoteVideoRef.current.srcObject = remoteStream;
            };
          });
          const localStream = await navigator.mediaDevices.getUserMedia({
            audio: false,
            video: true,
          });
          // 设置本地流
          localVideoRef.current.srcObject = localStream;
          // // 推入本地流
          localStream
            .getTracks()
            .forEach((track) => pc.addTrack(track, localStream));

          // setRTC(pc);
          // B端添加 offer
          pc.setRemoteDescription(offer);
          // B端生成 answer
          const answer = await pc.createAnswer();
          // 本地再设置answer
          await pc.setLocalDescription(answer);
          // 中转A端
          socket.emit("answer", {
            answer,
            user,
          });
          return true;
        },
        onCancel() {
          console.log("Cancel");
        },
      });
    });

    //A端接收到 answer
    socket.on("peer-answer", (res) => {
      console.log("A端收peer-answer", res);
      // 到这里应该是A端
      const { answer } = res;
      // const pc = RTCpc;

      // 本地再设置 answer
      pc.setRemoteDescription(answer).catch((err) => {
        console.log("AAAA", err);
      });
    });

    // 接收远程过来的 offer 后续
    socket.on("peer-candidate", (res) => {
      console.log("客户端接收peer-candidate", res);
      // const pc = RTCpc;
      const ice = new RTCIceCandidate({
        candidate: res.candidateJson.candidate,
        sdpMid: res.candidateJson.id,
        sdpMLineIndex: res.candidateJson.label,
      });

      pc?.addIceCandidate(ice);
    });
  }

  // 点击通话
  async function handlerCall() {
    if (!receiveUser) return;
    console.log("开始通话~~~~");
    // const pc = new RTCPeerConnection(null);
    // setRTC(pc);
    // const pc = RTCpc;

    const localStream = await navigator.mediaDevices.getUserMedia({
      audio: false,
      video: true,
    });

    createPeerConnection(() => {
      pc.onicecandidate = (e) => {
        if (e.candidate) {
          const candidate = {
            candidateJson: {
              label: e.candidate.sdpMLineIndex,
              id: e.candidate.sdpMid,
              candidate: e.candidate.candidate,
            },
            user: receiveUser.user,
          };
          console.log("AAA发送ice", e);

          socketObj.emit("candidate", candidate);
        }
      };

      //获取远端媒体流处理
      // handleRemoteStreamAdd
      pc.ontrack = (e) => {
        const remoteStream = e.streams[0];
        console.log("远端媒体流", e.streams);
        remoteVideoRef.current.srcObject = remoteStream;
      };
    });

    // 设置本地流
    localVideoRef.current.srcObject = localStream;
    // 推入本地流
    localStream.getTracks().forEach((track) => pc.addTrack(track, localStream));

    const offer = await pc.createOffer();
    await pc.setLocalDescription(offer); //本地设置offer
    // 发送给B端 offer
    socketObj.emit("offer", {
      user: receiveUser.user,
      offer,
    });
  }

  function handleOk(e) {}
  return (
    <div className={styles.container}>
      <div className={styles.header}>
        <div className={styles.loginBox}>
          <Input
            value={loginValue}
            style={{ width: "200px", marginRight: "20px" }}
            onChange={(e) => setLoginValue(e.target.value)}
          ></Input>
          {(function () {
            if (isLogin) {
              return <Button onClick={onLogout}>退出</Button>;
            } else {
              return <Button onClick={onLogin}>登录</Button>;
            }
          })()}
        </div>
        <Flex gap="4px 5px" wrap="wrap">
          {userInfo ? (
            <List.Item.Meta
              avatar={<Avatar src={userInfo.avatar} />}
              title={<span>{userInfo.username}</span>}
              description={`这是当前登录的人`}
            />
          ) : (
            <span>暂未登录</span>
          )}
        </Flex>
        <Flex gap="4px 0" wrap="wrap">
          <Input
            style={{ width: "200px", marginRight: "20px" }}
            onChange={(e) => setMessage(e.target.value)}
          ></Input>
          <Button onClick={onSendMessage}>发送消息</Button>
        </Flex>
        <div style={{ marginLeft: "20px" }}>
          {isLogin ? "已登录" : "未登录"}
        </div>
      </div>
      <div className={styles.view} style={{ height: "700px" }}>
        <div className={styles.userlist}>
          <Title style={{ textAlign: "center" }} level={5}>
            用户列表
          </Title>
          <List
            itemLayout="horizontal"
            dataSource={userList}
            renderItem={(item, index) => (
              <List.Item
                className={classnames(
                  item.socketId == receiveUser?.user.socketId
                    ? styles.activeUser
                    : ""
                )}
              >
                <List.Item.Meta
                  style={{ cursor: "pointer" }}
                  onClick={() => handleUserSay(item)}
                  avatar={<Avatar src={item.avatar} />}
                  title={<span>{item.username}</span>}
                  description={`我是第${index + 1}个用户`}
                />
              </List.Item>
            )}
          />
          {/* <ul className={styles.userlistUL}>
            <li className={styles.listLI}>yangshi</li>
          </ul> */}
        </div>
        <div className={styles.messagebox}>
          <div className={styles.receiveUser}>
            <Title style={{ textAlign: "center" }} level={4}>
              当前对话: {receiveUser?.user.username || "未选择"}
            </Title>
            <div style={{ textAlign: "right" }}>
              <Button onClick={handlerCall}>点击通话</Button>
            </div>
          </div>

          <ul>
            {messageList.map((item, index) => {
              return (
                <li
                  className={classnames(
                    styles.messageList,
                    item.sender.socketId != socketObj.id ? "" : styles.my
                  )}
                  key={index}
                >
                  <Avatar
                    className={styles.avatar}
                    src={item.sender.avatar}
                    shape="square"
                  ></Avatar>
                  <div className={styles.messageContent}>
                    <span>{item.sender.username}</span>
                    <p>{item.message}</p>
                  </div>
                </li>
              );
            })}
          </ul>
        </div>

        <div className={styles.video}>
          <Title style={{ textAlign: "center" }} level={5}>
            本地流
          </Title>
          <video
            autoPlay
            className={styles.videoLocal}
            ref={localVideoRef}
          ></video>
          <Title style={{ textAlign: "center" }} level={5}>
            远程流
          </Title>
          <video
            autoPlay
            className={styles.videoRemote}
            ref={remoteVideoRef}
          ></video>
        </div>
      </div>
    </div>
  );
}

export default SocketIndex;
